home *** CD-ROM | disk | FTP | other *** search
/ Motor Sport Digital Archive Collection 1960s / Motor Sport Digital Archive Collection 1960s.iso / main.swf / scripts / mx / collections / Sort.as < prev    next >
Encoding:
Text File  |  2008-05-21  |  15.3 KB  |  484 lines

  1. package mx.collections
  2. {
  3.    import flash.events.Event;
  4.    import flash.events.EventDispatcher;
  5.    import flash.system.ApplicationDomain;
  6.    import mx.collections.errors.SortError;
  7.    import mx.core.mx_internal;
  8.    import mx.resources.ResourceBundle;
  9.    import mx.utils.ObjectUtil;
  10.    import mx.utils.StringUtil;
  11.    
  12.    use namespace mx_internal;
  13.    
  14.    public class Sort extends EventDispatcher
  15.    {
  16.       private static var resourceNoComparator:String;
  17.       
  18.       private static var resourceFindRestriction:String;
  19.       
  20.       private static var resourceNoItems:String;
  21.       
  22.       private static var resourceFindCondition:String;
  23.       
  24.       private static var resourceUnknownMode:String;
  25.       
  26.       private static var resourceNonUnique:String;
  27.       
  28.       mx_internal static const VERSION:String = "2.0.1.0";
  29.       
  30.       public static const ANY_INDEX_MODE:String = "any";
  31.       
  32.       public static const FIRST_INDEX_MODE:String = "first";
  33.       
  34.       public static const LAST_INDEX_MODE:String = "last";
  35.       
  36.       private static var packageResources:ResourceBundle = ResourceBundle.getResourceBundle("collections",ApplicationDomain.currentDomain);
  37.       
  38.       loadResources();
  39.       
  40.       private var usingCustomCompareFunction:Boolean;
  41.       
  42.       private var _fields:Array;
  43.       
  44.       private var _compareFunction:Function;
  45.       
  46.       private var noFieldsDescending:Boolean = false;
  47.       
  48.       private var defaultEmptyField:SortField;
  49.       
  50.       private var fieldList:Array;
  51.       
  52.       private var _unique:Boolean;
  53.       
  54.       public function Sort()
  55.       {
  56.          fieldList = [];
  57.          noFieldsDescending = false;
  58.          super();
  59.       }
  60.       
  61.       private static function loadResources() : void
  62.       {
  63.          resourceNoItems = packageResources.getString("noItems");
  64.          resourceFindCondition = packageResources.getString("findCondition");
  65.          resourceFindRestriction = packageResources.getString("findRestriction");
  66.          resourceUnknownMode = packageResources.getString("unknownMode");
  67.          resourceNonUnique = packageResources.getString("nonUnique");
  68.          resourceNoComparator = packageResources.getString("noComparator");
  69.       }
  70.       
  71.       public function findItem(param1:Array, param2:Object, param3:String, param4:Boolean = false, param5:Function = null) : int
  72.       {
  73.          var compareForFind:Function = null;
  74.          var fieldsForCompare:Array = null;
  75.          var found:Boolean = false;
  76.          var objFound:Boolean = false;
  77.          var index:int = 0;
  78.          var lowerBound:int = 0;
  79.          var upperBound:int = 0;
  80.          var obj:Object = null;
  81.          var direction:int = 0;
  82.          var fieldName:String = null;
  83.          var hadPreviousFieldName:Boolean = false;
  84.          var i:int = 0;
  85.          var hasFieldName:Boolean = false;
  86.          var objIndex:int = 0;
  87.          var match:Boolean = false;
  88.          var prevCompare:int = 0;
  89.          var nextCompare:int = 0;
  90.          var items:Array = param1;
  91.          var values:Object = param2;
  92.          var mode:String = param3;
  93.          var returnInsertionIndex:Boolean = param4;
  94.          var compareFunction:Function = param5;
  95.          if(!items)
  96.          {
  97.             throw new SortError(resourceNoItems);
  98.          }
  99.          if(items.length == 0)
  100.          {
  101.             return returnInsertionIndex ? 1 : -1;
  102.          }
  103.          if(compareFunction == null)
  104.          {
  105.             compareForFind = this.compareFunction;
  106.             if(Boolean(values) && fieldList.length > 0)
  107.             {
  108.                fieldsForCompare = [];
  109.                hadPreviousFieldName = true;
  110.                i = 0;
  111.                while(true)
  112.                {
  113.                   if(i < fieldList.length)
  114.                   {
  115.                      fieldName = fieldList[i];
  116.                      if(fieldName)
  117.                      {
  118.                         try
  119.                         {
  120.                            hasFieldName = values[fieldName] !== undefined;
  121.                         }
  122.                         catch(e:Error)
  123.                         {
  124.                            hasFieldName = false;
  125.                         }
  126.                         if(hasFieldName)
  127.                         {
  128.                            if(!hadPreviousFieldName)
  129.                            {
  130.                               break;
  131.                            }
  132.                            fieldsForCompare.push(fieldName);
  133.                         }
  134.                         else
  135.                         {
  136.                            hadPreviousFieldName = false;
  137.                         }
  138.                      }
  139.                      else
  140.                      {
  141.                         fieldsForCompare.push(null);
  142.                      }
  143.                      continue;
  144.                   }
  145.                   if(fieldsForCompare.length == 0)
  146.                   {
  147.                      throw new SortError(resourceFindRestriction);
  148.                   }
  149.                   try
  150.                   {
  151.                      initSortFields(items[0]);
  152.                   }
  153.                   catch(initSortError:SortError)
  154.                   {
  155.                   }
  156.                   i++;
  157.                }
  158.                throw new SortError(StringUtil.substitute(resourceFindCondition,fieldName));
  159.             }
  160.          }
  161.          else
  162.          {
  163.             compareForFind = compareFunction;
  164.          }
  165.          found = false;
  166.          objFound = false;
  167.          index = 0;
  168.          lowerBound = 0;
  169.          upperBound = int(items.length - 1);
  170.          obj = null;
  171.          direction = 1;
  172.          while(!objFound && lowerBound <= upperBound)
  173.          {
  174.             index = Math.round((lowerBound + upperBound) / 2);
  175.             obj = items[index];
  176.             direction = !!fieldsForCompare ? compareForFind(values,obj,fieldsForCompare) : compareForFind(values,obj);
  177.             switch(direction)
  178.             {
  179.                case -1:
  180.                   upperBound = index - 1;
  181.                   break;
  182.                case 0:
  183.                   objFound = true;
  184.                   switch(mode)
  185.                   {
  186.                      case ANY_INDEX_MODE:
  187.                         found = true;
  188.                         break;
  189.                      case FIRST_INDEX_MODE:
  190.                         found = index == lowerBound;
  191.                         objIndex = index - 1;
  192.                         match = true;
  193.                         while(match && !found && objIndex >= lowerBound)
  194.                         {
  195.                            obj = items[objIndex];
  196.                            prevCompare = !!fieldsForCompare ? compareForFind(values,obj,fieldsForCompare) : compareForFind(values,obj);
  197.                            match = prevCompare == 0;
  198.                            if(!match || match && objIndex == lowerBound)
  199.                            {
  200.                               found = true;
  201.                               index = objIndex + (match ? 0 : 1);
  202.                            }
  203.                            objIndex--;
  204.                         }
  205.                         break;
  206.                      case LAST_INDEX_MODE:
  207.                         found = index == upperBound;
  208.                         objIndex = index + 1;
  209.                         match = true;
  210.                         while(match && !found && objIndex <= upperBound)
  211.                         {
  212.                            obj = items[objIndex];
  213.                            nextCompare = !!fieldsForCompare ? compareForFind(values,obj,fieldsForCompare) : compareForFind(values,obj);
  214.                            match = nextCompare == 0;
  215.                            if(!match || match && objIndex == upperBound)
  216.                            {
  217.                               found = true;
  218.                               index = objIndex - (match ? 0 : 1);
  219.                            }
  220.                            objIndex++;
  221.                         }
  222.                         break;
  223.                      default:
  224.                         throw new SortError(resourceUnknownMode);
  225.                   }
  226.                   break;
  227.                case 1:
  228.                   lowerBound = index + 1;
  229.                   break;
  230.             }
  231.          }
  232.          if(!found && !returnInsertionIndex)
  233.          {
  234.             return -1;
  235.          }
  236.          return direction > 0 ? index + 1 : index;
  237.       }
  238.       
  239.       public function get compareFunction() : Function
  240.       {
  241.          return usingCustomCompareFunction ? _compareFunction : internalCompare;
  242.       }
  243.       
  244.       public function set unique(param1:Boolean) : void
  245.       {
  246.          _unique = param1;
  247.       }
  248.       
  249.       public function sort(param1:Array) : void
  250.       {
  251.          var fixedCompareFunction:Function = null;
  252.          var uniqueRet1:Object = null;
  253.          var fields:Array = null;
  254.          var i:int = 0;
  255.          var sortArgs:Object = null;
  256.          var uniqueRet2:Object = null;
  257.          var items:Array = param1;
  258.          if(!items || items.length <= 1)
  259.          {
  260.             return;
  261.          }
  262.          if(usingCustomCompareFunction)
  263.          {
  264.             fixedCompareFunction = function(param1:Object, param2:Object):int
  265.             {
  266.                return compareFunction(param1,param2,_fields);
  267.             };
  268.             if(unique)
  269.             {
  270.                uniqueRet1 = items.sort(fixedCompareFunction,Array.UNIQUESORT);
  271.                if(uniqueRet1 == 0)
  272.                {
  273.                   throw new SortError(resourceNonUnique);
  274.                }
  275.             }
  276.             else
  277.             {
  278.                items.sort(fixedCompareFunction);
  279.             }
  280.          }
  281.          else
  282.          {
  283.             fields = this.fields;
  284.             if(Boolean(fields) && fields.length > 0)
  285.             {
  286.                sortArgs = initSortFields(items[0],true);
  287.                if(unique)
  288.                {
  289.                   if(Boolean(sortArgs) && fields.length == 1)
  290.                   {
  291.                      uniqueRet2 = items.sortOn(sortArgs.fields[0],sortArgs.options[0] | Array.UNIQUESORT);
  292.                   }
  293.                   else
  294.                   {
  295.                      uniqueRet2 = items.sort(internalCompare,Array.UNIQUESORT);
  296.                   }
  297.                   if(uniqueRet2 == 0)
  298.                   {
  299.                      throw new SortError(resourceNonUnique);
  300.                   }
  301.                }
  302.                else if(sortArgs)
  303.                {
  304.                   items.sortOn(sortArgs.fields,sortArgs.options);
  305.                }
  306.                else
  307.                {
  308.                   items.sort(internalCompare);
  309.                }
  310.             }
  311.             else
  312.             {
  313.                items.sort(internalCompare);
  314.             }
  315.          }
  316.       }
  317.       
  318.       public function propertyAffectsSort(param1:String) : Boolean
  319.       {
  320.          var _loc2_:int = 0;
  321.          var _loc3_:SortField = null;
  322.          if(usingCustomCompareFunction || !fields)
  323.          {
  324.             return true;
  325.          }
  326.          _loc2_ = 0;
  327.          while(_loc2_ < fields.length)
  328.          {
  329.             _loc3_ = fields[_loc2_];
  330.             if(_loc3_.name == param1 || _loc3_.mx_internal::usingCustomCompareFunction)
  331.             {
  332.                return true;
  333.             }
  334.             _loc2_++;
  335.          }
  336.          return false;
  337.       }
  338.       
  339.       private function internalCompare(param1:Object, param2:Object, param3:Array = null) : int
  340.       {
  341.          var _loc4_:int = 0;
  342.          var _loc5_:int = 0;
  343.          var _loc6_:int = 0;
  344.          var _loc7_:SortField = null;
  345.          _loc4_ = 0;
  346.          if(!_fields)
  347.          {
  348.             _loc4_ = noFieldsCompare(param1,param2);
  349.          }
  350.          else
  351.          {
  352.             _loc5_ = 0;
  353.             _loc6_ = !!param3 ? int(param3.length) : int(_fields.length);
  354.             while(_loc4_ == 0 && _loc5_ < _loc6_)
  355.             {
  356.                _loc7_ = SortField(_fields[_loc5_]);
  357.                _loc4_ = _loc7_.mx_internal::internalCompare(param1,param2);
  358.                _loc5_++;
  359.             }
  360.          }
  361.          return _loc4_;
  362.       }
  363.       
  364.       public function get unique() : Boolean
  365.       {
  366.          return _unique;
  367.       }
  368.       
  369.       private function noFieldsCompare(param1:Object, param2:Object, param3:Array = null) : int
  370.       {
  371.          var result:int = 0;
  372.          var a:Object = param1;
  373.          var b:Object = param2;
  374.          var fields:Array = param3;
  375.          if(!defaultEmptyField)
  376.          {
  377.             defaultEmptyField = new SortField();
  378.             try
  379.             {
  380.                defaultEmptyField.mx_internal::initCompare(a);
  381.             }
  382.             catch(e:SortError)
  383.             {
  384.                throw new SortError(StringUtil.substitute(resourceNoComparator,a));
  385.             }
  386.          }
  387.          result = defaultEmptyField.compareFunction(a,b);
  388.          if(noFieldsDescending)
  389.          {
  390.             result *= -1;
  391.          }
  392.          return result;
  393.       }
  394.       
  395.       override public function toString() : String
  396.       {
  397.          return ObjectUtil.toString(this);
  398.       }
  399.       
  400.       private function initSortFields(param1:Object, param2:Boolean = false) : Object
  401.       {
  402.          var _loc3_:Object = null;
  403.          var _loc4_:int = 0;
  404.          var _loc5_:SortField = null;
  405.          var _loc6_:int = 0;
  406.          _loc3_ = null;
  407.          _loc4_ = 0;
  408.          while(_loc4_ < fields.length)
  409.          {
  410.             SortField(fields[_loc4_]).mx_internal::initCompare(param1);
  411.             _loc4_++;
  412.          }
  413.          if(param2)
  414.          {
  415.             _loc3_ = {
  416.                "fields":[],
  417.                "options":[]
  418.             };
  419.             _loc4_ = 0;
  420.             while(_loc4_ < fields.length)
  421.             {
  422.                _loc5_ = fields[_loc4_];
  423.                _loc6_ = _loc5_.mx_internal::getArraySortOnOptions();
  424.                if(_loc6_ == -1)
  425.                {
  426.                   return null;
  427.                }
  428.                _loc3_.fields.push(_loc5_.name);
  429.                _loc3_.options.push(_loc6_);
  430.                _loc4_++;
  431.             }
  432.          }
  433.          return _loc3_;
  434.       }
  435.       
  436.       public function reverse() : void
  437.       {
  438.          var _loc1_:int = 0;
  439.          if(fields)
  440.          {
  441.             _loc1_ = 0;
  442.             while(_loc1_ < fields.length)
  443.             {
  444.                SortField(fields[_loc1_]).reverse();
  445.                _loc1_++;
  446.             }
  447.          }
  448.          noFieldsDescending = !noFieldsDescending;
  449.       }
  450.       
  451.       public function set fields(param1:Array) : void
  452.       {
  453.          var _loc2_:SortField = null;
  454.          var _loc3_:int = 0;
  455.          _fields = param1;
  456.          fieldList = [];
  457.          if(_fields)
  458.          {
  459.             _loc3_ = 0;
  460.             while(_loc3_ < _fields.length)
  461.             {
  462.                _loc2_ = SortField(_fields[_loc3_]);
  463.                fieldList.push(_loc2_.name);
  464.                _loc3_++;
  465.             }
  466.          }
  467.          dispatchEvent(new Event("fieldsChanged"));
  468.       }
  469.       
  470.       [Bindable("fieldsChanged")]
  471.       public function get fields() : Array
  472.       {
  473.          return _fields;
  474.       }
  475.       
  476.       public function set compareFunction(param1:Function) : void
  477.       {
  478.          _compareFunction = param1;
  479.          usingCustomCompareFunction = _compareFunction != null;
  480.       }
  481.    }
  482. }
  483.  
  484.